package com.heima.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.crm.common.contents.CommonMessageContent;
import com.heima.crm.common.contents.StatusContext;
import com.heima.crm.common.result.PageResult;
import com.heima.crm.common.result.Result;
import com.heima.crm.common.utils.*;
import com.heima.crm.mapper.CrUserMapper;
import com.heima.crm.mapper.DeptMapper;
import com.heima.crm.mapper.PostMapper;
import com.heima.crm.mapper.TransferMapper;
import com.heima.crm.pojos.dtos.ResetPasswordDto;
import com.heima.crm.pojos.entity.SysDept;
import com.heima.crm.pojos.entity.SysPost;
import com.heima.crm.pojos.entity.TbTransfer;
import com.heima.crm.pojos.entity.TbUser;
import com.heima.crm.pojos.logindto.LoginDto;
import com.heima.crm.pojos.user.DeleteDTO;
import com.heima.crm.pojos.user.UserPageDto;
import com.heima.crm.pojos.user.SaveUserDto;
import com.heima.crm.pojos.vos.GetUserVo;
import com.heima.crm.pojos.vos.ImportVo;
import com.heima.crm.pojos.vos.TbUserVo;
import com.heima.crm.service.CrUserService;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class CrUserServiceImpl implements CrUserService {
    @Resource
    private CrUserMapper crUserMapper;
    @Autowired
    private TransferMapper transferMapper;
    @Resource
    private DeptMapper deptMapper;


    /**
     * 用户登录
     *
     * @param loginDto
     * @return
     */
    @Override
    public Result login(LoginDto loginDto) {
        if (loginDto == null) return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        String captcha = CaptchaUtils.get(loginDto.getKid());

        if (!captcha.equals(loginDto.getCaptcha())) return Result.error(CommonMessageContent.VERIFICATION_CODE_ERROR);


        //TbUser tbUser = crUserMapper.selectOne(new LambdaQueryWrapper<TbUser>().eq(TbUser::getPhonenumber, loginDto.getPhoneNumber()));
        TbUser tbUser = crUserMapper.getOne(loginDto.getPhoneNumber());
        if (tbUser == null) return Result.error(CommonMessageContent.USER_DOES_NOT_EXIST);
        if ("1".equals(tbUser.getStatus())) return Result.error(CommonMessageContent.ACCOUNT_DEACTIVATED);
        //校验
        String password = DigestUtils.md5DigestAsHex((loginDto.getPassword() + CommonMessageContent.PASSWORD_SALT).getBytes());
        if (!tbUser.getPassword().equals(password)) {
            return Result.error(CommonMessageContent.WRONG_PASSWORD);
        }
        HashMap<String, Object> hm = new HashMap<>();
        hm.put("id", tbUser.getUserId());
        hm.put("name", tbUser.getNickName());
        hm.put("username", tbUser.getUserName());
        String jwt = JwtUtils.generateJwt(hm);

        CaptchaUtils.clear(loginDto.getKid());

        return Result.success(jwt);
    }

    /**
     * 动态分页查询
     *
     * @param userPageDto
     * @return
     */
    @Override
    public Result page(UserPageDto userPageDto) {
        if (userPageDto == null) {
            return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        }
        userPageDto.checkParam();
        LambdaQueryWrapper<TbUser> lqw = new LambdaQueryWrapper<>();
        lqw.eq(TbUser::getDelFlag, 0);
        if (userPageDto.getNickName() != null && !userPageDto.getNickName().equals("")) {
            lqw.like(TbUser::getNickName, userPageDto.getNickName());
        }
        if (userPageDto.getPhonenumber() != null && !userPageDto.getPhonenumber().equals("")) {
            lqw.like(TbUser::getPhonenumber, userPageDto.getPhonenumber());
        }
        if (userPageDto.getStatus() != null && !"".equals(userPageDto.getStatus())) {
            lqw.eq(TbUser::getStatus, userPageDto.getStatus());
        }
        if (userPageDto.getStartTime() != null || userPageDto.getEndTime() != null) {
            lqw.between(TbUser::getCreateTime, userPageDto.getStartTime(), userPageDto.getEndTime());
        }
        Page<TbUser> page = new Page<>(userPageDto.getPageNum(), userPageDto.getPageSize());
        page = crUserMapper.selectPage(page, lqw);

        List<TbUser> records = page.getRecords();
        if (records==null){
            return Result.error("未查询到数据");
        }
        List<TbUserVo> list =new ArrayList<>();
        for (TbUser record : records) {
            TbUserVo tbUserVo =new TbUserVo();
            BeanUtils.copyProperties(record,tbUserVo);
            SysDept sysDept = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getId, record.getDeptId()));
            if (sysDept!=null){
                tbUserVo.setDeptName(sysDept.getDeptName());
            }
            list.add(tbUserVo);
        }
        PageResult<TbUserVo> pageResult = new PageResult<>();
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(list);
        return Result.success(pageResult);
    }

    /**
     * 新增用户
     *
     * @param saveUserDto
     * @return
     */
    @Override
    public Result save(SaveUserDto saveUserDto) {
        if (saveUserDto == null) {
            return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        }
        Integer integer = Math.toIntExact(crUserMapper.selectCount(new LambdaQueryWrapper<TbUser>().eq(TbUser::getPhonenumber, saveUserDto.getPhonenumber())));
        if (integer > 0) {
            return Result.error(CommonMessageContent.USER_ALREADY_EXISTS);
        }
        Integer userCount = Math.toIntExact(crUserMapper.selectCount(new LambdaQueryWrapper<TbUser>().eq(TbUser::getUserName, saveUserDto.getUserName())));
        if (userCount > 0) {
            return Result.error(CommonMessageContent.USER_ALREADY_EXISTS);
        }
        TbUser tbUser = new TbUser();
        BeanUtils.copyProperties(saveUserDto, tbUser);
        tbUser.setCreateTime(LocalDateTime.now());
        tbUser.setUpdateTime(LocalDateTime.now());
        tbUser.setCreateBy(String.valueOf(BaseContext.getCurrentId()));
        tbUser.setUpdateBy(String.valueOf(BaseContext.getCurrentId()));
        tbUser.setStatus(String.valueOf(StatusContext.STATUS_DEACTIVATE));
        tbUser.setUserType(String.valueOf(saveUserDto.getRoleId()));
        tbUser.setPassword(DigestUtils.md5DigestAsHex((tbUser.getPassword() + CommonMessageContent.PASSWORD_SALT).getBytes()));
        crUserMapper.insert(tbUser);
        //如果是市场部的，添加转派信息

            TbTransfer tbTransfer = new TbTransfer();
            tbTransfer.setUserName(tbUser.getUserName());
            tbTransfer.setUserId(tbUser.getUserId());
            tbTransfer.setTel(tbUser.getPhonenumber());
            tbTransfer.setClueNum(0L);
            tbTransfer.setBusyNum(0L);
            tbTransfer.setCreateTime(LocalDateTime.now());
            tbTransfer.setCreateId(BaseContext.getCurrentId());
            transferMapper.insert(tbTransfer);

        return Result.success("添加成功");
    }

    /**
     * 导入用户
     *
     * @param excelFile
     * @return
     */
    @Resource
    private UserParsing userParsing;

    @Override
    public Result importUsers(MultipartFile excelFile) {
        ImportVo importVo = userParsing.pase(excelFile);
        return Result.success(importVo);
    }

    /**
     * 导出用户
     *
     * @return
     */
    @Override
    public Result export(HttpServletResponse response) {
        //2. 通过POI将数据写入到Excel文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/import-user.xlsx");
        List<TbUser> tbUsers = crUserMapper.selectList(null);
        if (tbUsers == null) {
            return Result.error(CommonMessageContent.USER_DOES_NOT_EXIST);
        }
        try {
            //基于模板文件创建一个新的Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(in);

            //获取表格文件的Sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            for (int j = 0; j < tbUsers.size(); j++) {
                XSSFRow row = sheet.createRow(j + 1);
                row.createCell(0).setCellValue(tbUsers.get(j).getDeptId());
                row.createCell(1).setCellValue(tbUsers.get(j).getUserName());
                row.createCell(2).setCellValue(tbUsers.get(j).getNickName());
                row.createCell(3).setCellValue(tbUsers.get(j).getUserType());
                row.createCell(4).setCellValue(tbUsers.get(j).getPhonenumber());
                row.createCell(5).setCellValue(tbUsers.get(j).getSex());
                row.createCell(6).setCellValue(tbUsers.get(j).getAvatar());
                row.createCell(7).setCellValue(tbUsers.get(j).getPassword());
                row.createCell(8).setCellValue(tbUsers.get(j).getStatus());
                row.createCell(9).setCellValue(tbUsers.get(j).getRemark());
                row.createCell(10).setCellValue(tbUsers.get(j).getPostId());
            }


            ServletOutputStream out = response.getOutputStream();
            excel.write(out);
            out.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException("导出失败！");
        }
        //3. 通过输出流将Excel文件下载到客户端浏览器

        return Result.success();
    }

    /**
     * 数据回显
     *
     * @param userId
     * @return
     */
    @Override
    public Result getUser(Long userId) {
        if (userId == null) {
            return Result.error(CommonMessageContent.INVALID_PARAMETER);
        }
        TbUser tbUser = crUserMapper.selectById(userId);
        if (tbUser == null) {
            return Result.error(CommonMessageContent.USER_DOES_NOT_EXIST);
        }
        String sex = tbUser.getSex();
        if ("1".equals(sex)){
            tbUser.setSex("男");
        } else if ("0".equals(sex)) {
            tbUser.setSex("女");
        }else {
            tbUser.setSex("未知");
        }
        String status = tbUser.getStatus();
        if ("1".equals(status)){
            tbUser.setStatus("停用");
        }else if ("0".equals(status)){
            tbUser.setStatus("正常");
        }else {
            tbUser.setStatus("未知");
        }
        GetUserVo getUserVo = new GetUserVo();
        BeanUtils.copyProperties(tbUser,getUserVo);
        SysDept sysDept = deptMapper.selectById(tbUser.getDeptId());
        getUserVo.setDeptName(sysDept.getDeptName());
        return Result.success(getUserVo);
    }

    /**
     * 修改用户信息
     *
     * @param tbUser
     * @return
     */
    @Override
    public Result updateUser(TbUser tbUser) {
        if (tbUser == null) {
            return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        }
        Integer integer = Math.toIntExact(crUserMapper.selectCount(new LambdaQueryWrapper<TbUser>().eq(TbUser::getUserName, tbUser.getUserName())));
        if (integer > 0) {
            return Result.error(CommonMessageContent.DUPLICATE_USER_NAME);
        }
        Integer integer1 = Math.toIntExact(crUserMapper.selectCount(new LambdaQueryWrapper<TbUser>().eq(TbUser::getPhonenumber, tbUser.getPhonenumber())));
        if (integer1 > 0) {
            return Result.error(CommonMessageContent.DUPLICATE_PHONE_NUMBER);
        }
        if (tbUser.getPassword()!=null){
            tbUser.setPassword(DigestUtils.md5DigestAsHex((tbUser.getPassword() + CommonMessageContent.PASSWORD_SALT).getBytes()));
        }
        crUserMapper.updateById(tbUser);
        return Result.success();

    }

    /**
     * 删除用户
     *
     * @param userId
     * @return
     */
    @Override
    public Result deleteUserById(List<Long> userId) {
        if (userId == null) {
            return Result.error(CommonMessageContent.INVALID_PARAMETER);
        }

        if (userId==null || userId.size()==0){
            return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        }
        for (Long aLong : userId) {
            crUserMapper.deleteByUserId(aLong);
        }

        return Result.success();
    }

    @Override
    public Result sure(String kid) {
        if (kid==null){
            return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        }
        String userReturn = CaptchaUtils.temporaryInsertUser(kid, crUserMapper);
        if (!"ok".equals(userReturn)){
            return Result.error(CommonMessageContent.UNKNOWN_ERROR);
        }

        return Result.success();
    }

    @Override
    public Result unsure(String kid) {
        if (kid==null){
            return Result.error(CommonMessageContent.PARAMETER_EXCEPTION);
        }
        CaptchaUtils.removeTemporarySetUser(kid);
        return Result.success();
    }

    @Override
    public Result getDept() {
        List<SysDept> sysDepts = deptMapper.selectList(null);
        return Result.success(sysDepts);
    }

    @Resource
    private PostMapper postMapper;

    @Override
    public Result getPost() {
        List<SysPost> sysPosts = postMapper.selectList(null);
        return Result.success(sysPosts);
    }


}
